package com.hanoi.wiki.manager.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.hanoi.wiki.dao.RoleDAO;
import com.hanoi.wiki.dao.UserDAO;
import com.hanoi.wiki.dao.UserEvaluationDAO;
import com.hanoi.wiki.dao.UserLogDAO;
import com.hanoi.wiki.dao.UserStatisticDAO;
import com.hanoi.wiki.exception.DataAccessException;
import com.hanoi.wiki.exception.FunctionalException;
import com.hanoi.wiki.manager.UserManager;
import com.hanoi.wiki.model.Role;
import com.hanoi.wiki.model.User;
import com.hanoi.wiki.model.UserEvaluation;
import com.hanoi.wiki.model.UserLog;
import com.hanoi.wiki.model.UserStatistic;
import com.hanoi.wiki.model.json.UserJson;

@Component
@Transactional
public class UserManagerImpl extends BaseManagerImpl implements UserManager {
	
	@Autowired
	private UserDAO userDAO;	
	
	@Autowired
	private UserEvaluationDAO evaluationDAO;
	
	@Autowired
	private UserStatisticDAO statisticDAO;
	
	@Autowired
	private UserLogDAO logDAO;
	
	@Autowired
	private RoleDAO roleDAO;

	public int save(UserJson json) throws FunctionalException {
		try {
			User user = new User(json);
			
			List<UserStatistic> statistics = new ArrayList<UserStatistic>();
			UserStatistic statistic;
			for(Integer i : json.getUserStatistic()) {
				statistic = statisticDAO.get(i);
				if (statistic != null) {
					statistics.add(statistic);
				}
			}
			
			List<UserLog> logs = new ArrayList<UserLog>();
			UserLog log;
			for(Integer i : json.getUserLog()) {
				log = logDAO.get(i);
				if (log != null) {
					logs.add(log);
				}
			}
			
			Role role = roleDAO.get(json.getRole());
			if(role != null) {
				user.setRole(role);
			}
			
			UserEvaluation evaluation = evaluationDAO.get(json.getUserEvaluation());
			if (evaluation != null) {
				user.setUserEvaluation(evaluation);
			}
			
			user.setUserStatistic(statistics);
			user.setUserLog(logs);
			
			return userDAO.saveUser(user);
		} catch (DataAccessException e) {
			log.error(" ",e);
		}
		return 0;
	}

	public UserJson get(Integer id) throws FunctionalException{
		try {
			return new UserJson(userDAO.get(id));
		} catch (DataAccessException e) {
			log.error(" ",e);
		}
		return null;
	}

	public List<UserJson> getList() throws FunctionalException {		
		List<UserJson> listUserJson = new ArrayList<UserJson>();
		List<User> listUser = userDAO.getList(); 
		try {
			for(User user : listUser) {				
				listUserJson.add(new UserJson(user));
			}
		} catch (DataAccessException e) {
			log.error(" ",e);
		}
		return listUserJson;
	}

	public void remove(Integer id) throws FunctionalException{
		try {
			if(userDAO.get(id) != null) {
				userDAO.remove(id);
			}
		} catch (DataAccessException e) {
			log.error(" ",e);
		}		
	}

	public void update(UserJson json) throws FunctionalException {
		try {
			User user = new User(json);
			
			List<UserStatistic> statistics = new ArrayList<UserStatistic>();
			UserStatistic statistic;
			for(Integer i : json.getUserStatistic()) {
				statistic = statisticDAO.get(i);
				if (statistic != null) {
					statistics.add(statistic);
				}
			}
			
			List<UserLog> logs = new ArrayList<UserLog>();
			UserLog log;
			for(Integer i : json.getUserLog()) {
				log = logDAO.get(i);
				if (log != null) {
					logs.add(log);
				}
			}
			
			Role role = roleDAO.get(json.getRole());
			if(role != null) {
				user.setRole(role);
			}
			
			UserEvaluation evaluation = evaluationDAO.get(json.getUserEvaluation());
			if (evaluation != null) {
				user.setUserEvaluation(evaluation);
			}
			
			user.setUserStatistic(statistics);
			user.setUserLog(logs);
			user.setId(json.getId());
			
			userDAO.update(user);
		} catch (DataAccessException e) {
			log.error(" ",e);
			e.printStackTrace();
		}		
	}

	public UserJson getUserByName(String userName) throws FunctionalException {
		try {
			if(userName != null) {
				return new UserJson(userDAO.getUserByName(userName));
			}
		} catch (DataAccessException e) {
			log.error(" ",e);
		}
		return null;
	}
}
